/**
 * 
 */
package com.xbang.core.config;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

import com.xbang.core.utils.ReflectionUtils;
import com.xbang.core.utils.TypeConverterUtils;

/**
 * @author dev.zhang
 * 
 */
public class AnnotationPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer implements BeanPostProcessor, InitializingBean {

	private static final Log logger = LogFactory.getLog(AnnotationPropertyPlaceholderConfigurer.class);

	private Properties properties;

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.springframework.beans.factory.config.BeanPostProcessor#
	 * postProcessAfterInitialization(java.lang.Object, java.lang.String)
	 */
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.springframework.beans.factory.config.BeanPostProcessor#
	 * postProcessBeforeInitialization(java.lang.Object, java.lang.String)
	 */
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

		// inject for field
		Field[] fields = bean.getClass().getDeclaredFields();

		for (Field field : fields) {

			if (field.isAnnotationPresent(Inject.class)) {
				Inject inject = field.getAnnotation(Inject.class);
				try {

					String value = properties.getProperty(inject.value());
					ReflectionUtils.setField(field, bean, value);

				} catch (Exception e) {

				}
			}
		}

		// inject for method
		Method[] methods = bean.getClass().getDeclaredMethods();

		for (Method method : methods) {

			if (method.isAnnotationPresent(Inject.class) && method.getParameterTypes().length == 1) {
				Inject inject = method.getAnnotation(Inject.class);
				try {
					String value = properties.getProperty(inject.value());
					method.invoke(bean, TypeConverterUtils.parse(value, method.getParameterTypes()[0]));

				} catch (Exception e) {

				}
			}

			if (method.isAnnotationPresent(InitMonth.class)) {
				try {
					method.invoke(bean, null);
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}

		return bean;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	public void afterPropertiesSet() throws Exception {
		this.properties = mergeProperties();
	}

}
